﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using LitJson;
using System.Reflection;
using System.Configuration;
using System.Collections.ObjectModel;
using System.ComponentModel;

namespace ScriptEditor.Commands
{
    public class Command
    {
        public enum COMMANDTYPE
        {
            Dialogue,
            ShowDialogue,
            HideDialogue,
            ParamInit,
            Param,
            Jump,
            Choice,
            Debug,
            Bg,
            BgTransform,
            BgTransformPath,
            ShowChar,
            HideChar,
            Investigation,
            CharTransform,
            CharJump,
            Music,
            SoundFX,
            ShowSprite,
            HideSprite,
            SpriteTransform,
            Map,
            ActionStart,
            UnlockContact,
            StartMessageSession,
            ChangeFace,
            AddBlog,
            ChangeScene,
            Naming,
            Vibration,
            Preload,
            Wait,
            Guide,
            CharRotation,
            SpriteRotation,
            CameraTF,
            CharAlpha,
            SpriteAlpha,
            MacroStart,
            MacroEnd,
            Macro,
            CameraShake,
            CharPath,
            CenterText,
            HideCenterText,
            CreateTextBox,
            Glitch,
            CreateMask,
            AddToMask,
            ShowMask,
            HideMask,
            ShowPrefab,
            CharColor,
            SpriteJump,
            Notification,
            MusicVolume,
            RemoveBlog,
            Trophy,
            AutoSave
        }
        protected COMMANDTYPE CommandType = COMMANDTYPE.Vibration;
        protected string Condition = "";
        protected string Id = "";
        protected string Text = "";
        protected string Value1 = "";
        protected string Value2 = "";
        protected string Value3 = "";
        protected string Value4 = "";
        protected string Value5 = "";
        protected string Value6 = "";
        protected string Value7 = "";
        protected string Value8 = "";
        protected string Value9 = "";
        protected string Value10 = "";
        protected string Value11 = "";
        protected string Value12 = "";
        protected string Value13 = "";
        protected string Value14 = "";
        protected bool Wait = false;


        public Command()
        {

        }
        public Command(JsonData json)
        {
            CommandType = (COMMANDTYPE)Enum.Parse(typeof(COMMANDTYPE), json["CommandType"].ToString());
            Condition = json["Condition"].ToString();
            Id = json["Id"].ToString();
            Text = json["Text"].ToString();
            Value1 = json["Value1"].ToString();
            Value2 = json["Value2"].ToString();
            Value3 = json["Value3"].ToString();
            Value4 = json["Value4"].ToString();
            Value5 = json["Value5"].ToString();
            Value6 = json["Value6"].ToString();
            Value7 = json["Value7"].ToString();
            Value8 = json["Value8"].ToString();
            Value9 = json["Value9"].ToString();
            Value10 = json["Value10"].ToString();
            Value11 = json["Value11"].ToString();
            Value12 = json["Value12"].ToString();
            Value13 = json["Value13"].ToString();
            Value14 = json["Value14"].ToString();
            Wait = true;
            if (!bool.TryParse(json["Wait"].ToString(), out Wait))
            {
                Wait = true;
            }
        }

        public string id
        {
            get
            {
                return Id;
            }
            set
            {
                Id = value;
            }
        }
        public string condition
        {
            get
            {
                return Condition;
            }
            set
            {
                Condition = value;
            }
        }
        public bool wait
        {
            get
            {
                return Wait;
            }
            set
            {
                Wait = value;
            }
        }
        COMMANDTYPE commandtype
        {
            get
            {
                return CommandType;
            }
            /*set
            {
                CommandType = value;
            }*/
        }

        //获取指令简略信息
        public override string ToString()
        {
            return CommandType.ToString();
        }

        //由父类根据COMMANDTYPE转换为对应子类
        public object ConvertCommand()
        {
            Type srcT = GetType();
            // 构造一个要转换对象实例
            object instance;
            Console.WriteLine(GetType().Namespace+"."+GetType().Name + "_" + commandtype.ToString());
            instance = Activator.CreateInstance(Type.GetType(GetType().Namespace + ".Command_" + commandtype.ToString()));

            // 这里指定搜索所有公开和非公开的字段
            FieldInfo[] srcFields = srcT.GetFields(BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Instance);

            // 将源头对象的每个字段的值分别赋值到转换对象里，因为假定字段都一样，这里就不做容错处理了
            foreach (FieldInfo field in srcFields)
            {
                instance.GetType().GetField(field.Name, BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Instance).
                    SetValue(instance, field.GetValue(this));
            }

            return instance;
        }

        public JsonData writeJson()    //写出剧本指令
        {
            JsonData json = new JsonData();
            json["CommandType"] = CommandType.ToString();
            json["Condition"] = Condition;
            json["Id"] = Id;
            json["Text"] = Text;
            json["Value1"] = Value1;
            json["Value2"] = Value2;
            json["Value3"] = Value3;
            json["Value4"] = Value4;
            json["Value5"] = Value5;
            json["Value6"] = Value6;
            json["Value7"] = Value7;
            json["Value8"] = Value8;
            json["Value9"] = Value9;
            json["Value10"] = Value10;
            json["Value11"] = Value11;
            json["Value12"] = Value12;
            json["Value13"] = Value13;
            json["Value14"] = Value14;
            json["Wait"] = Wait.ToString();
            return json;
        }  
        public static JsonData writeSum(List<Command> commands) //写出完整的剧本
        {
            JsonData json = new JsonData();
            for (int i = 0; i < commands.Count; i++)
            {
                json[i.ToString()] = commands[i].writeJson();
            }
            return json;
        }
        public static JsonData writeSum(ObservableCollection<Command> commands) //写出完整的剧本
        {
            JsonData json = new JsonData();
            for (int i = 0; i < commands.Count; i++)
            {
                json[i.ToString()] = commands[i].writeJson();
            }
            return json;
        }

        //向量和字符串之间转换
        public static string Vector2ToString(Vector2 vector)
        {
            return vector.x.ToString() + "|" + vector.y.ToString();
        }
        public static Vector2 StringToVector2(string vector)
        {
            string[] vector2 = vector.Split(new char[] { '|' });
            if (vector2.Length < 1 || vector2[0] == "")
            {
                return new Vector2 { x = 0, y = 0 };
            }
            if (vector2.Length < 2)
            {
                return new Vector2 { x = float.Parse(vector2[0]), y = 0 };
            }
            return new Vector2 { x = float.Parse(vector2[0]), y = float.Parse(vector2[1]) };
        }
        public static string Vector3ToString(Vector3 vector)
        {
            return vector.x.ToString() + "|" + vector.y.ToString() + "|" + vector.z.ToString();
        }
        public static Vector3 StringToVector3(string vector)
        {
            string[] vector3 = vector.Split(new char[] { '|' });
            if (vector3.Length <1||vector3[0] == "")
            {
                return new Vector3 { x = 0, y = 0, z = 0 };
            }
            if (vector3.Length < 2)
            {
                return new Vector3 { x = float.Parse(vector3[0]), y = 0, z = 0 };
            }
            if (vector3.Length < 3)
            {
                return new Vector3 { x = float.Parse(vector3[0]), y = float.Parse(vector3[1]), z = 0 };
            }
            return new Vector3 { x = float.Parse(vector3[0]), y = float.Parse(vector3[1]), z = float.Parse(vector3[2]) };
        }
    }
}
